package com.ncui.wisdomLearn.biz.user.service.impl;

import cn.dev33.satoken.stp.StpUtil;
import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.util.RandomUtil;
import cn.hutool.crypto.digest.DigestUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.ncui.wisdomLearn.api.dto.UserDTO;
import com.ncui.wisdomLearn.api.entity.User;
import com.ncui.wisdomLearn.api.vo.UserVO;
import com.ncui.wisdomLearn.biz.user.mapper.UserMapper;
import com.ncui.wisdomLearn.biz.user.service.RoleService;
import com.ncui.wisdomLearn.biz.user.service.UserRoleService;
import com.ncui.wisdomLearn.biz.user.service.UserService;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.StringUtils;

import java.util.List;
import java.util.stream.Collectors;

/**
 * 用户表(User)表服务实现类
 *
 * @author lvlele
 * @since 2025-01-03 00:05:13
 */
@Service
@Slf4j
@RequiredArgsConstructor
public class UserServiceImpl extends ServiceImpl<UserMapper, User> implements UserService {

    private final RoleService roleService;

    private final UserRoleService userRoleService;

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Boolean createUser(UserDTO userDTO) {
        User user = new User();
        BeanUtil.copyProperties(userDTO, user);

        // 生成随机盐值
        String salt = RandomUtil.randomString(6);
        user.setSalt(salt);
        // 密码加密：md5(password + salt)
        String encryptedPassword = DigestUtil.md5Hex(user.getPassword() + salt);
        user.setPassword(encryptedPassword);
        // 设置默认状态为正常
        user.setStatus(0);
        
        // 保存用户信息
        boolean saved = save(user);
        if (saved) {
            // 绑定用户和角色关系
            userRoleService.addUserRole(user.getUserId(), 2L);
        }
        return saved;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Boolean deleteUser(Long userId) {
        return removeById(userId);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Boolean updateUser(UserDTO userDTO) {
        User user = new User();
        BeanUtil.copyProperties(userDTO, user);

        // 如果修改了密码，需要重新加密
        User oldUser = getById(user.getUserId());
        if (oldUser != null && !oldUser.getPassword().equals(user.getPassword())) {
            String encryptedPassword = DigestUtil.md5Hex(user.getPassword() + oldUser.getSalt());
            user.setPassword(encryptedPassword);
            user.setSalt(oldUser.getSalt());
        }
        return updateById(user);
    }

    @Override
    public UserVO getUserById(Long userId) {
        User user = getById(userId);
        if (user == null) {
            return null;
        }
        return convertToVO(user);
    }

    @Override
    public Page<UserVO> getUserPage(Page<User> page, UserDTO userDTO) {
        LambdaQueryWrapper<User> wrapper = new LambdaQueryWrapper<>();
        // 根据用户名模糊查询
        wrapper.like(StringUtils.hasText(userDTO.getUsername()), User::getUsername, userDTO.getUsername())
                // 根据手机号精确查询
                .eq(StringUtils.hasText(userDTO.getPhone()), User::getPhone, userDTO.getPhone())
                // 根据邮箱精确查询
                .eq(StringUtils.hasText(userDTO.getEmail()), User::getEmail, userDTO.getEmail())
                // 根据状态查询
                .eq(userDTO.getStatus() != null, User::getStatus, userDTO.getStatus())
                // 按创建时间降序排序
                .orderByDesc(User::getCreateTime);

        Page<User> userPage = page(page, wrapper);
        Page<UserVO> voPage = new Page<>();
        BeanUtil.copyProperties(userPage, voPage, "records");
        voPage.setRecords(userPage.getRecords().stream().map(this::convertToVO).collect(Collectors.toList()));
        return voPage;
    }

    @Override
    public UserVO getUserByUsername(String username) {
        LambdaQueryWrapper<User> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(User::getUsername, username);
        User user = getOne(wrapper);
        return user != null ? convertToVO(user) : null;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Boolean updateUserStatus(Long userId, Integer status) {
        User user = new User();
        user.setUserId(userId);
        user.setStatus(status);
        return updateById(user);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Boolean resetPassword(Long userId, String newPassword) {
        User user = getById(userId);
        if (user == null) {
            return false;
        }
        // 生成新的盐值
        String salt = RandomUtil.randomString(6);
        // 加密新密码
        String encryptedPassword = DigestUtil.md5Hex(newPassword + salt);

        User updateUser = new User();
        updateUser.setUserId(userId);
        updateUser.setPassword(encryptedPassword);
        updateUser.setSalt(salt);
        return updateById(updateUser);
    }

    /**
     * 获取用户角色列表
     *
     * @param id 用户ID
     * @return 角色列表
     */
    public List<String> getUserRoleById(Long id) {
        return StpUtil.getRoleList(id);
    }

    /**
     * 判断用户是否为管理员
     *
     * @param id 用户ID
     * @return 是否为管理员
     */
    public Boolean getRoleById(Long id) {
        return StpUtil.hasRole(id, "admin");
    }

    /**
     * 将 User 实体转换为 UserVO
     *
     * @param user 用户实体
     * @return 用户VO
     */
    private UserVO convertToVO(User user) {
        if (user == null) {
            return null;
        }
        UserVO userVO = new UserVO();
        BeanUtil.copyProperties(user, userVO);
        List<Long> roleIds = userRoleService.getRoleIdsByUserId(user.getUserId());

        // 设置用户角色
        userVO.setRoles(roleService.listRolesByIds(roleIds));
        return userVO;
    }
}

